package com.glp.controller;

import com.glp.common.constants.FileConstants;
import com.glp.common.constants.GlpConstants;
import com.glp.common.resp.ApiResult;
import com.glp.common.util.MyUtil;
import com.glp.pojo.Report;
import com.glp.pojo.ReportAudit;
import com.glp.pojo.User;
import com.glp.pojo.dto.AuditDTO;
import com.glp.pojo.dto.ReportDTO;
import com.glp.services.ReportAuditService;
import com.glp.services.ReportService;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 中诺模板的报告
 */
@Controller
@RequestMapping("report")
public class ReportController {
    @Autowired
    private ReportService reportService;

    @Autowired
    private ReportAuditService reportAuditService;

    @GetMapping("/submit-view")
    public ModelAndView submitView(@RequestParam(required = false) Integer reportId) {
        ModelAndView mav = new ModelAndView("report/submit2");
        if (!ObjectUtils.isEmpty(reportId)) {
            User user = (User) SecurityUtils.getSubject().getPrincipal();
            Report report = reportService.getReportById(reportId);
            if (report == null) {
                return mav;
            }
            //判断 用户获取报告时 ， 是不是自己的报告 ， 防止非法请求
            if (user.getRoleId() == GlpConstants.SYS_ROLE04) {
                if (user.getUserId().equals(report.getCreateBy())) {
                    mav.addObject("report", report);
                } else {
                    return mav;
                }
            } else {
                mav.addObject("report", report);
            }
        }
        return mav;
    }

    @GetMapping("/client/list-view")
    public ModelAndView listView() {
        ModelAndView mav = new ModelAndView("report/client/list");
        return mav;
    }

    @GetMapping("/client/save-list-view")
    public ModelAndView saveListView() {
        ModelAndView mav = new ModelAndView("report/client/save-list");
        return mav;
    }

    @GetMapping("/admin/list")
    public ModelAndView adminListView(@RequestParam(required = false) Integer status) {
        ModelAndView mav = new ModelAndView("report/admin/list");
        mav.addObject("status", status);
        return mav;
    }

    /**
     * @param status 根据状态获取报告
     * @param client 根据分类获取报告
     * @return
     */
    @GetMapping("getList")
    @ResponseBody
    public List<ReportDTO> list(@RequestParam(required = false) Integer status,
                                @RequestParam(required = false) Integer client) {
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        List<ReportDTO> list;
        //如果是用户请求 ， 只获取用户自己的报告 ， 当status为空时 ，查询非保存状态的报告
        if (user.getRoleId() == GlpConstants.SYS_ROLE04) {
            list = reportService.getReportByStatusAndUId(status, user.getUserId());
        } else {
            list = reportService.getReportByStatus(status);
            if (!ObjectUtils.isEmpty(client) && client != 0) {
                list = list.stream()
                        .filter((reportDTO -> reportDTO.getCreateBy().equals(client) && reportDTO.getStatus() > GlpConstants.REPORT_STATUS0))
                        .collect(Collectors.toList());
            }
        }

        return list;
    }

    @PostMapping("remove")
    @ResponseBody
    public ApiResult removeReport(@RequestParam Integer reportId) {
        //判断报告是否可删除
        ReportAudit reportAudit = reportAuditService.getReportAuditByReportId(reportId);
        boolean con = reportService.judgeReportIsRemove(reportId, reportAudit.getStatus());
        if (con) {
            //删除保存的照片
            reportService.delReportImage(reportId);
            //删除报告
            reportService.remove(reportId);
            //删除审核进度
            reportAuditService.remove(reportId);
        }
        return new ApiResult();
    }

    @PostMapping("save")
    @ResponseBody
    public ApiResult saveReport(@RequestBody Report report) {
        User curUser = (User) SecurityUtils.getSubject().getPrincipal();
        int count;
        ApiResult result = new ApiResult();
        if (ObjectUtils.isEmpty(report)) {
            return new ApiResult(200, "请填写数据");
        }
        if(curUser.getRoleId() == GlpConstants.SYS_ROLE04 && !ObjectUtils.isEmpty(report.getReportId())){
            Report temp = reportService.getReportById(report.getReportId());
            if (temp.getStatus() == GlpConstants.REPORT_STATUS2
                    || temp.getStatus() == GlpConstants.REPORT_STATUS4
                    || temp.getStatus() == GlpConstants.REPORT_STATUS6
                    || temp.getStatus() == GlpConstants.REPORT_STATUS7) {
                return new ApiResult(500, temp.getReportId() + ":此报告状态无法进行修改，无法修改提交!!");
            }
        }
        try {
            //图片转格式
            base64LoadReport(report);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //说明报告第一次保存
        if (ObjectUtils.isEmpty(report.getReportId())) {
            //这里执行插入
            report.setCreateBy(curUser.getUserId());
            report.setCreateTime(new Date());
            report.setStatus(GlpConstants.REPORT_STATUS0);
            count = reportService.addReport(report, GlpConstants.REPORT_STATUS0);
        } else {
            //第n次保存
            //说明之前可能已经有图片在报告里面了 ， 这里先执行删除之前的照片之后再进行添加
            delReportOldImage(report);
            report.setUpdateTime(new Date());
            count = reportService.modifyReport(report);
        }
        if (count >= 1) {
            result.setData(report.getReportId());
        } else {
            result.setCode(500);
            result.setMessage("数据上传异常!");
        }
        return result;
    }

    @PostMapping("submit")
    @ResponseBody
    public ApiResult submitReport(@RequestBody Report report) {
        User curUser = (User) SecurityUtils.getSubject().getPrincipal();
        ApiResult result = new ApiResult();
        if (ObjectUtils.isEmpty(report)) {
            return new ApiResult(200, "请填写数据");
        }
        //验证报告编号是否重复
        Report temp = reportService.getReportById(report.getReportId());
        if (temp != null && temp.getStatus() != GlpConstants.REPORT_STATUS0) {
            return new ApiResult(500, temp.getReportId() + ":此报告已提交，无法重复提交!!");
        }
        int count;
        //说明是填完之后直接提交的
        if (ObjectUtils.isEmpty(report.getReportId())) {
            try {
                //图片转格式
                base64LoadReport(report);
            } catch (Exception e) {
                e.printStackTrace();
            }
            report.setCreateBy(curUser.getUserId());
            report.setCreateTime(new Date());
            report.setSubmitTime(new Date());
            report.setStatus(GlpConstants.REPORT_STATUS1);
            count = reportService.addReport(report, GlpConstants.REPORT_STATUS1);
        } else {
            //验证状态
            if (temp.getStatus() == GlpConstants.REPORT_STATUS2
                    || temp.getStatus() == GlpConstants.REPORT_STATUS4
                    || temp.getStatus() == GlpConstants.REPORT_STATUS6
                    || temp.getStatus() == GlpConstants.REPORT_STATUS7) {
                return new ApiResult(500, temp.getReportId() + ":此报告状态无法进行修改，无法修改提交!!");
            }
            try {
                //图片转格式
                base64LoadReport(report);
            } catch (Exception e) {
                e.printStackTrace();
            }
            //从保存页面跳转过来提交的
            delReportOldImage(report);
            report.setUpdateTime(new Date());
            report.setSubmitTime(new Date());
            report.setStatus(GlpConstants.REPORT_STATUS1);
            count = reportService.modifyReport(report);
            //修改状态
            reportAuditService.modifyStatusByReportId(report.getReportId(), GlpConstants.REPORT_STATUS1);
        }
        if (count >= 1) {
            result.setData(report.getReportId());
        } else {
            result.setCode(500);
            result.setMessage("数据上传异常!");
        }
        return result;
    }

    @PostMapping("audit")
    @ResponseBody
    public ApiResult reportPass(@RequestBody AuditDTO auditDTO) {
        User curUser = (User) SecurityUtils.getSubject().getPrincipal();
        boolean con = false;
        if (curUser.getRoleId() == GlpConstants.SYS_ROLE01) {
            con = true;
        } else {
            //状态 和 角色的判断
            if (auditDTO.getStatus() == GlpConstants.REPORT_STATUS2 || auditDTO.getStatus() == GlpConstants.REPORT_STATUS3) {
                if (curUser.getRoleId() == GlpConstants.SYS_ROLE03) {
                    con = true;
                }
            }
            if (auditDTO.getStatus() == GlpConstants.REPORT_STATUS4 || auditDTO.getStatus() == GlpConstants.REPORT_STATUS5) {
                if (curUser.getRoleId() == GlpConstants.SYS_ROLE02) {
                    con = true;
                }
            }
        }
        if (con) {
            int count = reportService.auditReport(auditDTO);
            return new ApiResult();
        } else {
            return new ApiResult(500, "非法操作！");
        }
    }

    @PostMapping("archive")
    @ResponseBody
    public ApiResult archive(@RequestBody AuditDTO auditDTO) {
        //todo 查看报告是否已打印？
        User curUser = (User) SecurityUtils.getSubject().getPrincipal();
        if (curUser.getRoleId() != GlpConstants.SYS_ROLE01) {
            return new ApiResult(500, "非法请求！");
        }
        reportService.modifyReportStatus(auditDTO.getReportId(), auditDTO.getStatus());
        return new ApiResult();
    }

    @GetMapping("getRejectMsg")
    @ResponseBody
    public ApiResult getRejectMsg(@RequestParam Integer reportId) {
        ReportAudit audit = reportAuditService.getReportAuditByReportId(reportId);
        if (audit.getStatus() == GlpConstants.REPORT_STATUS5) {
            return new ApiResult(200, audit.getRatifyMsg());
        } else if (audit.getStatus() == GlpConstants.REPORT_STATUS3) {
            return new ApiResult(200, audit.getAuditMsg());
        }
        return new ApiResult();
    }
    @PostMapping("resubmit")
    @ResponseBody
    public ApiResult resubmit(@RequestParam Integer reportId) {
        int count1 = reportService.resetReportStatus(reportId, GlpConstants.REPORT_STATUS1);
        return new ApiResult();
    }


    @GetMapping("print")
    public void exportReportExcel(@RequestParam Integer reportId, HttpServletResponse response) {
        Report report = reportService.getReportById(reportId);
        //todo 看情况是否需要 .. 角色验证
//        reportService.exportZNReportExcel(report, response);
        reportService.exportGLPReportExcel(report,response);
        //如果是签发通过的 进行报告打印 状态修改为已打印 , 其他状态打印只是测试 不改变报告状态
        if (report.getStatus() == GlpConstants.REPORT_STATUS4) {
            reportService.modifyReportStatus(reportId, GlpConstants.REPORT_STATUS6);
        }
    }

    @PostMapping("/android/submit")
    @ResponseBody
    public ApiResult androidReportSubmit(@RequestBody Report report){
        report.setCreateTime(new Date());
        report.setCreateBy(GlpConstants.ANDROID_USER_ID);
        report.setUpdateTime(new Date());
        try {
            //图片转格式
            base64LoadReport(report);
        } catch (Exception e) {
            e.printStackTrace();
        }
        int count = reportService.addReport(report,GlpConstants.REPORT_STATUS0);
        if(count == 1){
            return new ApiResult();
        }else{
            return new ApiResult(500,"请求失败！");
        }
    }

    /**
     * 删除之前保存的照片
     *
     * @param report
     */
    private void delReportOldImage(Report report) {
        Report temp = reportService.getReportById(report.getReportId());
        delImage(report.getJxztzp(), temp.getJxztzp());
        delImage(report.getClmpzp(), temp.getClmpzp());
        delImage(report.getFdjmpzp(), temp.getFdjmpzp());
        delImage(report.getHclzzzp(), temp.getHclzzzp());
        delImage(report.getJczp(), temp.getJczp());
        delImage(report.getJgzp(), temp.getJgzp());
    }

    private void delImage(String newPath, String virPath) {
        if (StringUtils.isEmpty(virPath)) {
            return;
        }
        if (virPath.equals(newPath + "")) {
            return;
        }
        String fileName = virPath.substring(virPath.lastIndexOf("/"));
        File file = new File(FileConstants.REPORT_IMG_LOCAL_URL + fileName);
        if (file.exists()) {
            file.delete();
        }
    }

    /**
     * base64转图片 , 并存本地
     */
    private void base64LoadReport(Report report) {
        report.setJxztzp(MyUtil.Base64ToImage(report.getJxztzp()));
        report.setClmpzp(MyUtil.Base64ToImage(report.getClmpzp()));
        report.setFdjmpzp(MyUtil.Base64ToImage(report.getFdjmpzp()));
        report.setHclzzzp(MyUtil.Base64ToImage(report.getHclzzzp()));
        report.setJczp(MyUtil.Base64ToImage(report.getJczp()));
        report.setJgzp(MyUtil.Base64ToImage(report.getJgzp()));
    }
}
